#ifndef MCU_COM_H
#define MCU_COM_H

#include "main.h"

//MCU调试结构，包括读写、IAP、块数据下载功能
//此包前方可加aa 02，后方可加sum
//本协议不支持多节点总线通信，由外层协议支持
#pragma pack(1)
typedef struct //8字节
{
	u8 cmd	:4; //最高位为0：为了与调试结构协议兼容，从10开始。见IAP_CMD_TYPE
	u8 type	:3; //类型：0:u8，1:u16，2:u32，3:操作失败
	u8 down	:1; //最高位为1：下行块数据，低7bit为数据长度
	u8 para; //指令参数
			// 请求数据  4bit为包序号,下发数据里没有索引位置，要跟请求序号一致才行
	u8 d[0]; //此处作为数据包的起始
	u16 d16; //此处作为数据包的起始
	u32 d32; //
} COM_DBG; //通用调试结构
#pragma pack()
typedef enum 
{
	DBG_D_R=0, //读内存指令
	DBG_D_W=1, //写内存指令
	DBG_D_SAVE=2, //保存指令
	DBG_U_REP=3, //回复读指令

	IAP_D_REQ=4, //IAP请求
		//	para=0请求帧，data为bin的crc16,d32为下载总长B，MCU用11应答，12请求数据
		//	para=1查询UID，MCU用5应答
		//	para=2重启，无应答
		//	此处可定义253个额外指令
	IAP_U_ANS=5, //IAP应答
		//	para为请求类型
		//	d16=0准许(成功),1不准许(失败),3crc错误,4烧写错误,5烧写成功
	IAP_U_GETD=6, //请求数据：d32为所需的数据偏移
} IAP_CMD_TYPE;
typedef enum 
{
	MCU_SWITCH_APP=0, //切换到应用程序(BootLoader调用switch_2_addr，或者重启)
	MCU_RESET=1, //系统软复位
	MCU_IAP_FINISH=2, //结束iap，主程序可以此时烧写flash，并跳转
	MCU_SAVE=3, //保存配置
} MCU_SYS_CMD; //MCU系统指令

extern u32 uid; //唯一ID

#ifdef __cplusplus
extern "C"
{
#endif
extern u16 mem_off_tab[12];//内存区域表

void iap_rx(u8 *p,int n); //IAP的接收函数
void iap_poll(void); //100Hz

///////////////////////////////////////////////////////////////////////
//				IAP外部接口
extern int (*iap_cmd_fun)(MCU_SYS_CMD c); //iap调用主程序的指令
extern void (*iap_tx)(u8 *p,int n); //IAP数据发送函数
//IAP数据存储，主程序可以缓存在内存，也可以直接烧flash
extern void (*iap_store)(int off,u8 *p,int n); //输入存储偏置，数据指针，长度

extern const u8 *binbuf_p; //程序缓存位置，但不能写只能读。写是通过函数来写
extern int binbuf_n; //程序缓存长度
extern u8 *iap_txbuf; //发送缓冲区，至少sizeof(COM_DBG)那么长。若有块数据外发，则更大
extern int iap_txbuf_len; //发送缓冲区长度
#ifdef __cplusplus
}
#endif

#endif

